# coding: utf-8


'''
ssh到指定节点, 检查磁盘利用率, 如果 > [阈值], 发送100MB+的文件列表
'''

import re
import os
import time
import commands
from libs import mailSender
from ConfigParser import ConfigParser as Parser

#### 运行条件 :  # 默认在25运行, 25到3个节点已配置互信

Threshold = 0.9    # 磁盘使用率阈值
File_Size = '100M' # find > 100MB文件列表

Usage_Log = './log/disk_usage.log'
Warn_Log = './log/warning.log'
History_Log = './log/history.log'
Split_Line = '-' * 80

UAT_IP_Rc = re.compile(r'172.\d{1,3}\.\d{1,3}\.\d{1,3}')
Percent_Rc = re.compile(r'\d{1,}.?\d%')

def ip_host_map(hosts="/etc/hosts"):
    ip_host_map = {}
    for ln in open(hosts):
        grep_ip = UAT_IP_Rc.findall(ln)
        if grep_ip:
            ip = grep_ip[0].strip()
            host = ln.strip().split(ip)[-1].strip()
            ip_host_map[ip] = host
    # print ip_host_map
    return ip_host_map

def current_time():
    return time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))

def get_usage(space_info):
    # 从space_info中解析出磁盘使用率(过滤百分比最大的一项)
    print '---------------------'
    print space_info
    print '---------------------'
    percents = Percent_Rc.findall(space_info)
    percents = [int(x.strip('%')) for x in percents]
    percents = sorted(percents, reverse=True)
    print 'usage desc sorts : ', percents
    return float(percents[0]) / 100

def get_disk_space(node_ip):
    try:
        space_info = commands.getoutput('sh get_disk_space.sh %s' % node_ip)
        _time = current_time()
        node_info = '\n%s\n%s\t%s\n%s\n%s' % (Split_Line, node_ip, _time, Split_Line, space_info)
        with open(Usage_Log, 'a') as log:
            log.write(node_info)
        with open(History_Log, 'a') as history:
            history.write(node_info)
        return get_usage(space_info)
    except Exception as e:
        print e
        return 0.0

def get_big_files(node_ip, host_name):
    big_files = commands.getoutput('sh get_big_files.sh %s %s' % (node_ip, File_Size))
    _time = current_time()
    files_title = '文件列表: > %s' % File_Size
    file_info = '\n%s\n%s\t%s\n%s\n%s' % (Split_Line, files_title, _time, Split_Line, big_files)
    with open(Warn_Log, 'a') as log:
        log.write(">>>>>>>> %s [%s]<<<<<<<<<<<\n" % (node_ip, host_name))
        log.write(file_info + "\n\n")
    with open(Usage_Log, 'a') as log:
        log.write(file_info + "\n\n")

def get_current_host_ip():
    return commands.getoutput("ifconfig | grep -v 127.0.0.1 |grep inet | awk '{print $2}'").strip()

def get_current_host_disk_space():
    node_ip = get_current_host_ip()
    try:
        space_info = commands.getoutput('df -h')
        _time = current_time()
        node_info = '\n%s\n%s\t%s\n%s\n%s' % (Split_Line, node_ip, _time, Split_Line, space_info)
        with open(Usage_Log, 'a') as log:
            log.write(node_info)
        with open(History_Log, 'a') as history:
            history.write(node_info)
        return get_usage(space_info)
    except Exception as e:
        print e
        return 0.0

def get_current_host_big_files():
    node_ip = get_current_host_ip()
    big_files = commands.getoutput('find / -size +%s -exec ls -lh {} \;' % File_Size)
    _time = current_time()
    files_title = '文件列表: > %s' % File_Size
    file_info = '\n%s\n%s\t%s\n%s\n%s' % (Split_Line, files_title, _time, Split_Line, big_files)
    with open(Warn_Log, 'a') as log:
        log.write(">>>>>>>> %s <<<<<<<<<<<\n" % node_ip)
        log.write(file_info + "\n\n")
    with open(Usage_Log, 'a') as log:
        log.write(file_info + "\n\n")

def send_usage_mail():
    mail_sender = mailSender.MailSender('./mail.conf')
    threshold = str(Threshold * 100) + '%'
    available = str((1 - Threshold) * 100) + '%'
    title = '【磁盘监控】测试机磁盘可用空间小于 %s' % available
    msg = ''
    proc = 'find: `/proc/'
    mapping = 'reverse mapping checking'

    # 过滤"find: `/proc/" 和 "reverse mapping checking"
    for x in open(Warn_Log).readlines():
        if not x.strip().startswith(proc) and not x.strip().startswith(mapping):
            msg += x
    # mail_sender.send_mail_to_author(title, msg)
    mail_sender.send_mail_to_team(title, msg)

def init_log():
    # truncate  Usage_Log
    with open(Warn_Log, 'w') as log:
        log.write('磁盘空间监控_告警_大文件列表')
    with open(Usage_Log, 'w') as log:
        log.write('磁盘空间监控')

def reachable(ip):
    p = os.popen("ping -c 1 %s" % ip)
    x = p.read()
    p.close()
    if "100% packet loss" in x:
        print "ping failed %s" % ip
        return False
    return True

def main():
    init_log()
    send_mail = False
    for ip, host_name in ip_host_map().items():
        print '----------------------'
        print ip, ">>>", host_name
        if not reachable(ip):
            continue
        usage = get_disk_space(ip)
        if usage > Threshold:
            get_big_files(ip, host_name)
            send_mail = True
    # print 'current host disk info'
    usage = get_current_host_disk_space()
    if usage > Threshold:
        get_current_host_big_files()
        send_mail = True

    if send_mail:
        send_usage_mail()


if __name__ == '__main__':
    main()

